#!perl

use strict;
use warnings;

use Encode;
use FindBin;
use Plack::Builder;
use Plack::Request;
use Text::Xslate;
use Unicode::RecursiveDowngrade;
use YAML;

use Google::API::Client;
use OAuth2::Client;


my $client = Google::API::Client->new;
my $service = $client->build('plus', 'v1');

my $tx = Text::Xslate->new(
    syntax => 'TTerse',
);
my $config = YAML::LoadFile("$FindBin::Bin/config.yaml");
my $dat_file = "$FindBin::Bin/token.dat";

my $app = sub { 
    my $env = shift;
    my $request = Plack::Request->new($env);

    my $redirect_uri = sprintf qq(http://localhost:%s/callback), $request->port;
    my $auth_driver = OAuth2::Client->new({
        auth_uri => Google::API::Client->AUTH_URI,
        token_uri => Google::API::Client->TOKEN_URI,
        client_id => $config->{client_id},
        client_secret => $config->{client_secret},
        redirect_uri => $redirect_uri,
        auth_doc => $service->{auth_doc},
    });

    if ($request->path eq '/callback') {
        my $code = $request->param('code');
        my $access_token = $auth_driver->exchange($code);
        open my $fh, '>', $dat_file;
        if ($fh) {
            print $fh JSON->new->encode($access_token);
            close $fh;
        }
        my $response = $request->new_response;
        $response->redirect(sprintf qq(http://localhost:%s/play), $request->port);
        return $response->finalize;
    }

    my $content;
    if ($request->path eq '/play') {
        my $access_token;
        if (-f $dat_file) {
            open my $fh, '<', $dat_file;
            if ($fh) {
                local $/;
                $access_token = JSON->new->decode(<$fh>);
                close $fh;
            }
            $auth_driver->token_obj($access_token);
        }

        # Call people.get method
        my $me = $service->people->get(body => { userId => 'me' })->execute({ auth_driver => $auth_driver });

        # Call activities.list method
        my $activities_doc = $service->activities->list(body => { userId => 'me', collection => 'public' })->execute({ auth_driver => $auth_driver });
        my @activities;
        for my $activity (@{$activities_doc->{items}}) {
            push @activities, Unicode::RecursiveDowngrade->new->downgrade($activity);
        }

        # Call activities.get method
        my $first_activity = $activities[0];
        $activities_doc = $service->activities->get(body => { activityId => $first_activity->{id} })->execute({ auth_driver => $auth_driver });
        my $top_activity_content = encode_utf8($activities_doc->{object}{content});
        my %param = (
            me => $me,
            activities => \@activities,
            top_activity_content => $top_activity_content,
        );
        $content = $tx->render('play.html', \%param);
    } else {
        my $auth_url = $auth_driver->authorize_uri;
        my %param = (
            auth_url => $auth_url,
        );
        $content = $tx->render('login.html', \%param); 
    }
    my $response = $request->new_response(200);
    $response->content_type('text/html; charset=utf8');
    $response->content($content);
    $response->finalize;
};

builder {
    $app;
};

__END__
